로딩 중이에요... 🐣
[코담]
웹개발·실전 프로젝트·AI까지, 파이썬·장고의 모든것을 담아낸 강의와 개발 노트
24 Ajax + CSRF 토큰을 활용한 좋아요 | ✅ 편저: 코담 운영자
24강 - Ajax + CSRF 토큰을 활용한 좋아요 요청 구현
호출, fetch, csrf✅ 목표
-
PostSerializer
에csrf_token
필드를 추가하여, 게시글 JSON 응답 가장에 CSRF 토큰을 포함 -
Ajax(
fetch
) 호출 시 CSRF 토큰을 포함하여 정수적인 POST 요청 구현
1. CSRF 토큰 배포와 Serializer 구조
PostSerializer 개발
from django.middleware.csrf import get_token
class PostSerializer(serializers.ModelSerializer):
comment_post = CommentSerializer(many=True)
author = FeedAuthorSerializer()
csrf_token = serializers.SerializerMethodField()
class Meta:
model = models.Post
fields = (
"id",
"image",
"caption",
"image_likes",
"author",
"comment_post",
"csrf_token",
)
def get_csrf_token(self, obj):
request = self.context.get('request')
return get_token(request) if request else None
설명
-
SerializerMethodField()
를 사용하여 직접get_csrf_token()
정의 -
context['request']
를 통해 현재 요청에서 CSRF 토큰 추출
2. context 설정 방법
뷰나 뷰셋에서 context 에 request
객체를 건너쓰면, 사이러리어에서 request
토큰 가져오기 가능
방법 예시:
class PostViewSet(viewsets.ModelViewSet):
queryset = models.Post.objects.all()
serializer_class = PostSerializer
def get_serializer_context(self):
context = super().get_serializer_context()
context['request'] = self.request
return context
토큰 포함 Ajax 호출 - JS 구현
파일: django_instagram/static/js/posts/loadMorePosts.js
// 좋아요 / 좋아요 취소 Ajax 호출
async function handleLikeClick(postId, csrfToken, target) {
console.log("handleLikeClick : ", postId, csrfToken, target);
const iTag = target.querySelector("i");
const likeButton = target;
if (likeButton.disabled) return;
likeButton.disabled = true;
try {
const response = await fetch(`/api/posts/${postId}/post_like/`, {
method: "POST",
headers: {
"X-CSRFToken": csrfToken,
},
});
const data = await response.json();
console.log("response : ", data);
if (!response.ok || !data.success) {
console.log(" 좋아요 API 호출 중 오류가 발생했습니다.: ", data.error);
throw new Error(data.message || "좋아요 API 호출 중 오류가 발생했습니다.");
}
if (data.message === "like") {
iTag.classList.replace("fa-heart-o", "fa-heart");
iTag.classList.replace("text-gray-500", "text-red-500");
} else {
iTag.classList.replace("fa-heart", "fa-heart-o");
iTag.classList.replace("text-red-500", "text-gray-500");
}
target.querySelector("#like-count-" + postId).innerText = data.like_count;
} catch (error) {
console.error("Error liking post:", error);
} finally {
likeButton.disabled = false;
}
}
✅ 요약
-
Django에서 CSRF 토큰은 보안을 위해 필요
-
PostSerializer
에서get_csrf_token()
을 통해 CSRF 토큰을 전달 -
뷰셋에서
context['request'] = self.request
처리 필수 -
JS에서 fetch 요청 시 헤더에
"X-CSRFToken"
값을 포함해야 서버가 요청을 허용함
이 방식을 통해 API와 JS 간의 안전한 POST 요청 구현이 가능합니다.